#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

#include <pthread.h>
#include <mqueue.h>
#include <fcntl.h>           /* Pour les constantes O_* */
#include <sys/stat.h>        /* Pour les constantes « mode » */


#include <config.h>
/*
#include <simulation.h>
#include <conditionnement.h>
#include <destockage.h>
#include <impression.h>
#include <palette.h>
#include <stockage.h>
#include <archivage.h>
#include <erreur.h>
*/
#include <ecriture_windows.h>
#include <lecture_windows.h>




// -----------------------------------------------------------------
// ICI J'AJOUTE DES INCLUDE + DEFINE PROPRES A CE TEST
// ----------------------------------------------------------------

#include "bal_posting.h"
#include "balr_demarrage.h"
#include "balr_archivage.h"
#include "balr_destockage.h"
#include "balr_decision_err.h"

#define NB_THREAD_TEST 7
#define NB_BAL_TEST 5

#define T_LECTURE_TEST 0
#define T_ECRITURE_TEST 1
#define T_BAL_POSTING 2
#define T_BALR_DEMARRAGE 3
#define T_BALR_ARCHIVAGE 4
#define T_BALR_DESTOCKAGE 5
#define T_BALR_DECISION_ERR 6 

// -------------------------------------------------------------------
// FIN DE L'AJOUT
// ------------------------------------------------------------------

// REMARQUES:
// - a la creation des BAL, j'ai remplacé "NB_BAL" par "NB_BAL_TEST"
// - a la creation des threads, j'ai remplacé "NB_THREAD" par "NB_THREAD_TEST"
// - je n'utilise pas la priorité des threads


int main()
{

	/* Creation des mécanismes de communication */
	mqd_t bal[NB_BAL];
	int index=0;
	struct mq_attr param={0,10,sizeof(MSG_versErreur),0};
	//bal[index++]=mq_open(BAL_versErreur,O_CREAT,PERMISSION,param);
	
	//param.mq_msgsize=sizeof(MSG_retErreur);
	//bal[index++]=mq_open(BAL_retErreur,O_CREAT,PERMISSION,param);
	
	param.mq_maxmsg=10;
	param.mq_msgsize=sizeof(MSG_versArchivage);
	bal[index++]=mq_open(BAL_versArchivage,O_CREAT,PERMISSION,param);
	
	param.mq_maxmsg=10;
	param.mq_msgsize=sizeof(MSG_versEcriture);
	bal[index++]=mq_open(BAL_versEcriture,O_CREAT,PERMISSION,param);
	
	param.mq_maxmsg=1;
	param.mq_msgsize=sizeof(MSG_decisionErreur);
	bal[index++]=mq_open(BAL_decisionErreur,O_CREAT,PERMISSION,param);
	
	/*
	param.mq_maxmsg=1;
	param.mq_msgsize=sizeof(MSG_carton);
	bal[index++]=mq_open(BAL_versImpression,O_CREAT,PERMISSION,param);
	bal[index++]=mq_open(BAL_versPalette,O_CREAT,PERMISSION,param);
	bal[index++]=mq_open(BAL_versStockage,O_CREAT,PERMISSION,param);
	*/
	
	param.mq_maxmsg=10;
	param.mq_msgsize=sizeof(MSG_versDestockage);
	bal[index++]=mq_open(BAL_versDestockage,O_CREAT,PERMISSION,param);
	
	param.mq_maxmsg=1;
	param.mq_msgsize=sizeof(MSG_demarrage);
	bal[index++]=mq_open(BAL_demarrage,O_CREAT,PERMISSION,param);
	

	/* ----- mutex */
	pthread_mutex_t mutex_SHM_Stock;
	MutexSHMStock=&mutex_SHM_Stock;
	pthread_mutex_init(MutexSHMStock,NULL);
	
	pthread_mutex_t mutex_SHM_OF;
	MutexSHMOF=&mutex_SHM_OF;
	pthread_mutex_init(MutexSHMOF,NULL);
	
	/* ----- zone de stockage */
	SHM_Stockage laZoneDeStockage;
	/* ----- initialisation */
	laZoneDeStockage.nbPaletteA=50;
	laZoneDeStockage.nbPaletteB=50;

	ZoneStockage=&laZoneDeStockage;
	
	/* ----- ordre de fabrication */
	SHM_ParametresOF lOrdreDeFabrication;
	/* ----- initialisation */
	lOrdreDeFabrication.numLot=1;
	lOrdreDeFabrication.nbPaletteA=0;
	lOrdreDeFabrication.taillePaletteA=0;
	lOrdreDeFabrication.tailleCartonA=0;
	lOrdreDeFabrication.nbPaletteB=0;
	lOrdreDeFabrication.taillePaletteB=0;
	lOrdreDeFabrication.tailleCartonB=0;
	
	OrdreFabrication=&lOrdreDeFabrication;


	
	/* Lancement de la simulation */
	//LancerSimu();
	
	/* Configuration et lancement des threads */
	/* ----- Création paramètres ordonnancement */
	/*	
	pthread_attr_t attr;
	struct sched_param schedParam;
	pthread_t threads[NB_THREAD];

	pthread_attr_init(&attr);
	pthread_attr_setschedpolicy(& attr, SCHED_FIFO);
	pthread_attr_setinheritsched(& attr, PTHREAD_EXPLICIT_SCHED);
	*/

	/* ----- Configuration thread Mère */
	//pthread_setschedprio(pthread_self(),PRIO_MERE);
	


	// ------------------------------------------------------------------------
	// ICI J'AI CARREMENT REMPLACE TON "LANCEMENT DES THREADS" PAR LE MIEN
	// ------------------------------------------------------------------------

	/* ----- Lancement des threads */
	pthread_t threads[NB_THREAD_TEST];

	/* ----- Lecture */
	pthread_create(&(threads[T_LECTURE_TEST]), NULL,LectureWindows,NULL);

	/* ----- Ecriture */
	pthread_create(&(threads[T_ECRITURE_TEST]), NULL,EcritureWindows,NULL);

	/* ----- BAL_Posting */
	pthread_create(&(threads[T_BAL_POSTING]), NULL,BalPosting,NULL);

	/* ----- BALR_Demarrage */
	pthread_create(&(threads[T_BALR_DEMARRAGE]), NULL,BALRdemarrage,NULL);

	/* ----- BALR_Archivage */
	pthread_create(&(threads[T_BALR_ARCHIVAGE]),NULL,BALRarchivage,NULL);

	/* ----- BALR_Destockage */
	pthread_create(&(threads[T_BALR_DESTOCKAGE]),NULL,BALRdestockage,NULL);

	/* ----- BALR_Decision_Err */
	pthread_create(&(threads[T_BALR_DECISION_ERR]), NULL,BALRdecisionErr,NULL);
	

	// --------------------------------------------------------------------------------
	// IDEM ICI J'AI REMPLACE TON "FIN DE L'APPLICATION PAR LE MIEN
	// --------------------------------------------------------------------------------
	
	/* Fin de l'application */
	// Les threads LectureWindows et EcritureWindows doivent se détruire d'eux memes.
	// Attente sur Lecture pour détruire les threads de simulation
	pthread_join(threads[T_LECTURE_TEST],NULL);
	/* ----- Destruction des threads */
	//BALR_Decision_Err
	pthread_cancel(threads[T_BALR_DECISION_ERR]);
	//BALR_Destockage
	pthread_cancel(threads[T_BALR_DESTOCKAGE]);
	//BALR_Archivage
	pthread_cancel(threads[T_BALR_ARCHIVAGE]);
	//BALR_Demarrage
	pthread_cancel(threads[T_BALR_DEMARRAGE]);
	//BAL_Posting
	pthread_cancel(threads[T_BAL_POSTING]);

	// ---------------------------------------------------------------------------------
	// FIN DES REMPLACEMENTS
	// ---------------------------------------------------------------------------------


	
	/* Arret de la simulation */
	//ArreterSimu();
	
	/* Destruction des mécanismes de communication */
	/* ----- mutex */
	pthread_mutex_destroy(MutexSHMStock);
	pthread_mutex_destroy(MutexSHMOF);
	/* ----- BaL */
	index=0;
	//mq_close(bal[index++]);
	//mq_unlink(BAL_versErreur);
	//mq_close(bal[index++]);
	//mq_unlink(BAL_retErreur);
	mq_close(bal[index++]);
	mq_unlink(BAL_versArchivage);
	mq_close(bal[index++]);
	mq_unlink(BAL_versEcriture);
	mq_close(bal[index++]);
	mq_unlink(BAL_decisionErreur);
	//mq_close(bal[index++]);
	//mq_unlink(BAL_versImpression);
	//mq_close(bal[index++]);
	//mq_unlink(BAL_versPalette);
	//mq_close(bal[index++]);
	//mq_unlink(BAL_versStockage);
	mq_close(bal[index++]);
	mq_unlink(BAL_versDestockage);
	mq_close(bal[index++]);
	mq_unlink(BAL_demarrage);
	
	/* Fermeture du journal de log */
	//fclose(journal);
	
	exit(EXIT_SUCCESS);
}
